/*
 * PlateauIhm.java
 * Classe principale du plateau de jeu.
 */



package Risk.IHM;

import Risk.IHM.MenuConnexion.EtapeJeu;

import Risk.Moteur.Jeu;
import Risk.Moteur.Joueur;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.JTextPane;
import javax.swing.JToolBar;
import javax.swing.border.BevelBorder;
import javax.swing.text.MutableAttributeSet;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;

/**
 * IMPORTANT les boutons Valider et annuler n'ont aucune raison d'exister vu que
 * la gestion des deplacements et le renfort sont geres soit par des fenetres soit
 * directement par le plateau de jeu
 *
 * @author nicoleta
 */
public class PlateauIhm extends JFrame implements ActionListener {

    // variables statiques
    private static final String		CHEMIN_ICONS     = "Images/Icons/";
    private static final String		CHEMIN_PLATEAUX  = "Images/PlateauxImg/";
    private static final String[]	IMG_ICONS_BOUT   = { "Carte.jpg", "menu.png", "des.png", "options.png" };
    private static final long		serialVersionUID = 1L;
    public static PlateauIhm		plateauIhm;
    private ChoixCarteIHM		cci     = null;
    private FenetreOptions		options = null;
    private ImageCarte			imgCarte;

    // test initialisation de la partie
    private JButton	jbCartes, jbMenu, jbTirDes, jbParam;
    private JButton	jbDeselectionne, jbFinPhase, jbFinPartie;
    private JLabel	jlCoulJoueurCour, jlNomJoueurCour, jlNbArmJouCour;
    private JPanel	jpJoueurCourant, jpJoueursEnCours;
    private JPanel	jpTextArea;
    public JTextArea	jtaConsole;
    public JTextPane	jtaInfo;

    // toolbar principale
    private JToolBar	jtbPrincipale;

    // composants graphiques
    private JTabbedPane	jtpFenetre;
    private JPanel	pPlateau;

    // jeu virtuel
    private Jeu	risk;

    /**
     * Constructeur
     * @param risk - le jeu virtuel
     */
    public PlateauIhm(Jeu risk, boolean... display) {
	super("Plateau jeu");
	this.risk             = risk;
	PlateauIhm.plateauIhm = this;

	final EtapeJeu	s = MenuConnexion.etape.PARTIE_COMMENCEE;

	// initialisation plateau
	this.setLayout(new BorderLayout());
	this.setBackground(Color.WHITE);
	initComponents(this);
	this.setSize(1024, 768);
	this.setResizable(false);
	this.addWindowListener(new WindowAdapter() {
	    @Override
	    public void windowClosing(WindowEvent w) {
		setVisible(false);
		MenuConnexion.menuConnect.setVisible(true);
		MenuConnexion.menuConnect.setEnabled(true);
		MenuConnexion.menuConnect.updateCommandButtons(s.PARTIE_COMMENCEE);
	    }
	});

	if (display.length == 0) {
	    this.setVisible(true);
	} else {
	    this.setVisible(display[ 0 ]);
	}
    }

    public void actionPerformed(ActionEvent e) {
	Object	o = e.getSource();

	// si l'on a appuye sur le bouton cartes de la toolbar
	// une fenetre avec gridlayout dynamique affiche les cartes du joueur en cours
	if (o.equals(jbCartes)) {

	    // Patern singleton : avoir qu'un seul objet ChoixCarteIHM
	    cci = ChoixCarteIHM.getInstance();
	    cci.setFrame(this);
	    cci.refreshCartes();
	    cci.setVisible(true);
	}

	// changement de phase de jeu
	if (o.equals(jbFinPhase)) {
	    if (!(risk.getPhase() == Jeu.RENFORT) || risk.testFinRenfort()) {
		risk.phaseSuivante();
	    }
	}

	// retour au menu du jeu
	if (o.equals(jbMenu)) {
	    this.dispose();
	    MenuConnexion.menuConnect.updateCommandButtons(MenuConnexion.etape.PARTIE_COMMENCEE);
	    MenuConnexion.menuConnect.setVisible(true);
	}

	// tirage des des
	if (o.equals(jbTirDes)) {

	    // tirage des des
	    TirageDes.getInstance(imgCarte.getSource(), imgCarte.getDestination(), this);

	    // affichage du tirage aux des dans le textArea d'information
	}

	// fenetre options
	if (o.equals(jbParam)) {
	    options = FenetreOptions.getInstance(imgCarte);
	}

	// fin de partie  enmission secrete
	if (o.equals(jbFinPartie)) {
	    if (ConnexionServeurIHM.CONNECTE) {
		getJtaConsole().append(getRisk().getTc().finDePartie());
	    }

	    finPartie(risk.getJoueurCourant());

	    // Popup
	}

	if (o.equals(jbDeselectionne)) {
	    imgCarte.effaceSelection();
	    repaint();
	}
    }

    /**
     *
     * @return
     */
    public void finPartie(Joueur jGagnant) {
	int	reponse = JOptionPane.showConfirmDialog(this,
			      "Partie terminee. Le gagnant est " + jGagnant.getNom()
			      + "\n\nVoulez-vous retourner au menu principal ?", " Fin de partie ",
				  JOptionPane.YES_NO_OPTION);

	if (reponse == JOptionPane.YES_OPTION) {
	    this.dispose();
	    MenuConnexion.menuConnect.updateCommandButtons(MenuConnexion.etape.DEBUT);
	    MenuConnexion.menuConnect.setVisible(true);
	}
    }

    /**
     * initialisation des composantes graphiques sur la frame
     * @param f - frame parent
     * ne pas mettre les images en dur
     */
    public void initComponents(JFrame f) {
	jtpFenetre = new JTabbedPane();

	// creation de la toolbar du bas de la fenetre avec boutons et textarea
	jtbPrincipale = new JToolBar();

	ImageIcon	ii = new ImageIcon(CHEMIN_ICONS + IMG_ICONS_BOUT[ 0 ]);

	// met l'icone des cartes bonus a l'echelle
	ii.setImage(ii.getImage().getScaledInstance(48, 48, Image.SCALE_DEFAULT));
	jbCartes = new JButton(" CARTES ", ii);
	jbMenu   = new JButton(" MENU ", new ImageIcon(CHEMIN_ICONS + IMG_ICONS_BOUT[ 1 ]));
	jbTirDes = new JButton(" ATTAQUE ! ", new ImageIcon(CHEMIN_ICONS + IMG_ICONS_BOUT[ 2 ]));
	jbParam  = new JButton(" OPTIONS ", new ImageIcon(CHEMIN_ICONS + IMG_ICONS_BOUT[ 3 ]));
	jbCartes.addActionListener(this);
	jbMenu.addActionListener(this);
	jbTirDes.addActionListener(this);
	jbTirDes.setEnabled(false);
	jbParam.addActionListener(this);
	jpTextArea = new JPanel(new BorderLayout());

	// textarea qui affiche des informations sur les coups joues - MILIEU
	jtaInfo = new JTextPane();

	StyledDocument	doc = jtaInfo.getStyledDocument();

	// alignement au centre du texte
	MutableAttributeSet	standard = new SimpleAttributeSet();

	StyleConstants.setAlignment(standard, StyleConstants.ALIGN_CENTER);
	doc.setParagraphAttributes(0, 0, standard, true);
	jtaInfo.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED, Color.DARK_GRAY, Color.LIGHT_GRAY));
	jtaInfo.setFont(new Font("Arial", Font.BOLD, 12));
	jtaInfo.setBackground(Color.WHITE);
	jtaInfo.setEditable(false);
	majPanneau();

	// BAS
	panelJoueurCourant();

	// HAUT
	jpJoueursEnCours = panelCoulJoueurs();

	// ajout du HAUT, MILIEU et BAS au jpanel
	jpTextArea.add(jtaInfo, BorderLayout.CENTER);
	jpTextArea.add(jpJoueursEnCours, BorderLayout.NORTH);
	jpTextArea.add(jpJoueurCourant, BorderLayout.SOUTH);

	// paneau qui contient les boutos d'actions
	JPanel	jpBoutAction = new JPanel();

	// teste si le jeu est de type "conquette" ou "mission secrete"
	if (risk.getTypePartie() == Jeu.CONQUERIR_LE_MONDE) {
	    jpBoutAction.setLayout(new GridLayout(2, 1));
	} else {
	    jpBoutAction.setLayout(new GridLayout(3, 1));
	}

	jbDeselectionne = new JButton("Deselect.");
	jbFinPhase      = new JButton("Fin de phase");
	jbFinPartie     = new JButton("Fin de partie");
	jbDeselectionne.addActionListener(this);
	jbFinPhase.addActionListener(this);
	jbFinPartie.addActionListener(this);
	jpBoutAction.add(jbDeselectionne);
	jpBoutAction.add(jbFinPhase);

	if (risk.getTypePartie() == Jeu.MISSIONS_SECRETES) {
	    jpBoutAction.add(jbFinPartie);
	}

	// ajout des composantes a la toolbar
	jtbPrincipale.add(jbMenu);
	jtbPrincipale.add(jbParam);
	jtbPrincipale.add(jbCartes);
	jtbPrincipale.add(jbTirDes);
	jtbPrincipale.add(jpTextArea);
	jtbPrincipale.add(jpBoutAction);
	jtbPrincipale.setFloatable(false);
	imgCarte = new ImageCarte(CHEMIN_PLATEAUX + "carte2.dat", CHEMIN_PLATEAUX + "carte2.png", this);

	// paneau qui sert pour le debogage et ou on affiche tout ce qui se passe sur le plateau
	jtaConsole = new JTextArea();
	jtaConsole.setLineWrap(true);
	jtaConsole.setWrapStyleWord(true);
	jtaConsole.setBackground(Color.WHITE);
	jtaConsole.setEditable(false);

	JScrollPane	scrollPane = new JScrollPane(jtaConsole);

	pPlateau = new JPanel(new BorderLayout());
	pPlateau.setBackground(Color.WHITE);
	pPlateau.add(imgCarte, BorderLayout.CENTER);
	jtpFenetre.addTab("Plateau de jeu", pPlateau);
	jtpFenetre.addTab("Messages envoyees vers serveur", scrollPane);
	jtpFenetre.setOpaque(true);
	jtpFenetre.setBackground(Color.WHITE);
	f.add(jtpFenetre, BorderLayout.CENTER);
	f.add(jtbPrincipale, BorderLayout.SOUTH);
    }

    public void majListeCouleur() {
	jpTextArea.remove(jpJoueursEnCours);
	jpJoueursEnCours = panelCoulJoueurs();
	jpTextArea.add(jpJoueursEnCours, BorderLayout.NORTH);
    }

    public void majPanneau() {
	switch (risk.getPhase()) {
	case Jeu.INITIALISATION :
	    modifierTexte("Phase initialisation " + risk.getJoueurCourant() + "\n"
			  + "Cliquez sur un pays pour y placer un soldat");

	    break;

	case Jeu.RENFORT :
	    modifierTexte("Phase renfort " + risk.getJoueurCourant() + "\nPlacez vos soldats");

	    break;

	case Jeu.ATTAQUE :
	    modifierTexte("Phase attaque " + risk.getJoueurCourant() + "\nChoisissez le pays attaquant");

	    break;

	case Jeu.MANOEUVRE :
	    modifierTexte("Phase manoeuvre " + risk.getJoueurCourant() + "\nChoisissez le pays de depart");

	    break;

	default :
	    System.out.println("Erreur dans initcomponent");

	    break;
	}
    }

    // methode qui mdifie le texte du jtextpane information
    public void modifierTexte(String s) {
	jtaInfo.setText(s.toUpperCase());
    }

    /**
     *
     * @param tailleGrid - en fonction du nb de joueurs configures au debut
     * @param c - tableau de coueurs present sur le fenetre configNouvellePartie
     * @return - le panel qui se trouve en haut du JTextArea d'information
     */

    // IMPORTANT : mettre a jour le panel quand un joueur perd et sort du jeu
    public JPanel panelCoulJoueurs() {
	JPanel	boutJoueurs = new JPanel(new GridLayout(1, risk.getJoueurs().size()));

	for (Joueur j : risk.getJoueurs()) {
	    if (!risk.estMort(j)) {

		// creation des boutons avec le nb de joueurs et leur couleur
		JButton	jb = new JButton();

		jb.setBackground(j.getCouleur());
		boutJoueurs.add(jb);
	    }
	}

	return boutJoueurs;
    }

    /**
     * MET LA COULEUR,LE NOM ET LE NOMBRE D'ARMEES DU JOUEUR COURANT
     * sur le panel jpJoueurCourant
     */
    public void panelJoueurCourant() {

	// si le panel na pas deja ete cree
	if (jpJoueurCourant == null) {
	    jpJoueurCourant = new JPanel(new GridLayout(1, 3));

	    // si le panel est deja initie
	} else {
	    jpJoueurCourant.removeAll();
	}

	jlCoulJoueurCour = new JLabel();
	jlCoulJoueurCour.setOpaque(true);

	/* couleur joueur courant */
	jlCoulJoueurCour.setBackground(risk.getJoueurCourant().getCouleur());

	/* nom joueur courant */
	jlNomJoueurCour = new JLabel("Nom joueur : " + risk.getJoueurCourant().getNom());

	/* nbArmees joueur courant */
	jlNbArmJouCour = new JLabel("Reserve d'armees : " + risk.getReserveJoueurCourant());
	jpJoueurCourant.add(jlCoulJoueurCour);
	jpJoueurCourant.add(jlNomJoueurCour);
	jpJoueurCourant.add(jlNbArmJouCour);
	jpJoueurCourant.updateUI();
    }

    /**
     * methode de remplacement de la carte en fonction de ce que un joueur a choisit comme carte
     * @param fichierDonnees - fichier *.dat contenant les couleurs de chaque pays et leur nom
     * @param image - nom de l'image de la carte utilisee
     */
    public void remplacerCarte(String fichierDonnees, String image) {
	pPlateau.remove(imgCarte);
	imgCarte = new ImageCarte(fichierDonnees, image, this);
	setImgCarte(imgCarte);
	pPlateau.add(imgCarte, BorderLayout.CENTER);
	this.remove(jtpFenetre);
	this.add(jtpFenetre, BorderLayout.CENTER);
	jtpFenetre.updateUI();
	modifierTexte("");
    }

    public ImageCarte getImgCarte() {
	return imgCarte;
    }

    public JButton getJbTirDes() {
	return jbTirDes;
    }

    public JTextArea getJtaConsole() {
	return jtaConsole;
    }

    /**
     * recupere le jeu virtuel
     * @return le jeu virtuel
     */
    public Jeu getRisk() {
	return risk;
    }

    public void setImgCarte(ImageCarte imgCarte) {
	this.imgCarte = imgCarte;
    }

    void setJBTirDe(boolean b) {
	jbTirDes.setEnabled(b);
    }

    public void setJbTirDesEnabled(boolean b) {
	this.jbTirDes.setEnabled(b);
    }
}
